package com.xhwl.centiotdata.utils;

import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.codec.binary.Base64;
import org.springframework.util.StringUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Copyright (C),1998-2022, 兴海物联
 * FileName: FaceImageUtil
 * Author: XuChang
 * Date: 2022/4/28 15:49
 * Description: 人脸图片处理工具
 * History:
 */
@Slf4j
public class FaceDataUtil {

    /**
     * 科拓人脸图片base64后需要添加的固定前缀
     */
    private static final String FACE_PIC_PREFIX = "data:image/jpg;base64,";

    /**
     * 不压缩范围 最小值
     */
    private static final long MIN_IMAGE_SIZE = 10 * 1024;

    /**
     * 不压缩范围 最大值
     */
    private static final long MAX_IMAGE_SIXE = 200 * 1024;
    /**
     * 可接受压缩的最大尺寸，大于这个尺寸，直接放弃压缩
     */
    private static final long COMPRESS_MAX_SIZE = 10 * 1024 * 1024;

    private static final long MAX_IMAGES_DATA_SIZE = 1024 * 1024;


    public static void main(String[] args) {
        getFaceData("https://cent.xymind.net:19000/bucket-test/8f17b74c7f0b4377902ea840037c2021.jpg");
    }

    public static String getFaceData(String faceUrl) {
        if (StringUtils.isEmpty(faceUrl)) {
            return "";
        }
        if (faceUrl.startsWith(FACE_PIC_PREFIX)) {
            return faceUrl;
        }
        try {
            return downLoad(faceUrl);
        } catch (Exception e) {
            log.error("图片压缩异常", e);
            return Base64Utils.imageUrlToBase64(faceUrl);
        }
    }

    private static String downLoad(String picUrl) throws IOException {
        ByteArrayOutputStream data = new ByteArrayOutputStream();
        try {
            // 创建URL
            URL url = new URL(picUrl);
            byte[] by = new byte[1024];
            // 创建链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            InputStream is = conn.getInputStream();
            // 将内容读取内存中
            int len;
            while ((len = is.read(by)) != -1) {
                data.write(by, 0, len);
            }
            // 关闭流
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        byte[] source = data.toByteArray();

        if (data.size() > COMPRESS_MAX_SIZE) {
            throw new RuntimeException("超过最大图片限制尺寸300k ！！!");
        } else if (data.size() >= MIN_IMAGE_SIZE && data.size() <= MAX_IMAGE_SIXE) {
            return new String(Base64.encodeBase64(source));
        }

        log.info("原始大小：" + source.length);
        byte[] bytes1 = onThumbnails(source);
        log.info("转换后大小：" + bytes1.length);
        return new String(Base64.encodeBase64(bytes1));
    }

    private static byte[] onThumbnails(byte[] bytes) throws IOException {
        // 图片大于1m的 压缩最多三次
        if (bytes.length > MAX_IMAGE_SIXE) {
            for (int times = 0; times < 10; times++) {
                bytes = thumbnailsByByte(bytes, 0.5f, 0.5f);
                if (bytes.length <= MAX_IMAGE_SIXE) {
                    break;
                }
            }
        }
        return bytes;
    }

    public static byte[] thumbnailsByByte(byte[] bytes, double area, double size) throws IOException {
        log.info("开始压图片缩，压缩前大小：{}kb", (bytes.length / 1024));
        InputStream in = new ByteArrayInputStream(bytes);
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        Thumbnails.of(in).scale(area).outputQuality(size).toOutputStream(out);
        bytes = out.toByteArray();
        log.info("结束图片压缩，压缩后大小：{}kb", (bytes.length / 1024));
        return bytes;
    }

}
